package cate.game.role.res.worldtree.addition;

import cate.common.table.d.GDObj;
import cate.common.table.d.GDOperation;
import cate.common.table.res.worldtree.row.HeroShareBaseRow;
import cate.common.table.res.worldtree.row.WorldTreeAdditionBaseRow;
import cate.common.table.res.worldtree.row.WorldTreeAdditionScaleRow;
import cate.common.util.GameResult;
import cate.game.attr.FightAttr;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.RoleDependent;
import cate.game.role.res.worldtree.msg.WorldTreeAdditionDataResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.apache.commons.lang3.StringUtils;


@NoteClass("世界树加成")
public class WorldTreeAddition extends RoleDependent {
    @NoteField("加成等级")
    public int level;

    @NoteField("炼制时的等级")
    public int refineLevel;

    @NoteField("炼制开始时间")
    public long refineBeginTime;

    @NoteField("炼制结束时间")
    public long refineExpireTime;

    @NoteField("炼制数量, 为0就是没炼制")
    public int refineNum;

    public GameResult<Void> levelUp() {
        GameResult<Void> r = new GameResult<>();
        HeroShareBaseRow baseRow = getBase();
        if (baseRow == null || baseRow.openStarNeed > getMaxStar()) {
            return r.fail("加成功能未开启");
        }
        WorldTreeAdditionBaseRow additionBaseRow = role.getGame().table.worldTree.additionBase.get(level);
        if (additionBaseRow == null) {
            return r.fail("当前无法升级");
        }
        if (StringUtils.isBlank(additionBaseRow.consumeStr)) {
            return r.fail("等级已经升满啦");
        }
        GameResult<MixResItem> consumeRes = new MixRes(additionBaseRow.consumeStr).consume(role);
        if (!consumeRes.ok()) {
            role.getGame().notice.tipResItem(role, consumeRes.data);
            return r.fail(consumeRes);
        }
        level += 1;
        if (refineNum > 0 && System.currentTimeMillis() < refineExpireTime) {
            int remainNum = (int) ((refineExpireTime - System.currentTimeMillis()) / (additionBaseRow.refineSeconds * 1000));
            if (remainNum > 0) {
                long remainBeginTime = refineExpireTime - remainNum * additionBaseRow.refineSeconds * 1000L;
                additionBaseRow = role.getGame().table.worldTree.additionBase.get(level);
                refineExpireTime = remainBeginTime + remainNum * additionBaseRow.refineSeconds * 1000L;
            }
        }
        noticeUpdate();
        role.getBase().updatePower();
        role.getHistory().action.worldTreeAdditionLevel(level);
        return r;
    }

    public GameResult<Void> beginRefine(int wantRefineNum) {
        GameResult<Void> r = new GameResult<>();
        HeroShareBaseRow baseRow = getBase();
        if (baseRow == null || baseRow.openStarNeed > getMaxStar()) {
            return r.fail("加成功能未开启");
        }
        if (wantRefineNum <= 0) {
            return r.fail("请选择正确的炼制数量");
        }
        if (this.refineNum > 0) {
            if (refineExpireTime > System.currentTimeMillis()) {
                return r.fail("涓流之息炼制中");
            }
            return r.fail("请先领取涓流之息");
        }
        WorldTreeAdditionBaseRow additionBaseRow = role.getGame().table.worldTree.additionBase.get(level);
        if (additionBaseRow == null) {
            return r.fail("当前无法炼制");
        }
        if (wantRefineNum > additionBaseRow.limitNum) {
            return r.fail("炼制数量有误");
        }
        GameResult<MixResItem> consumeRes = new MixRes(GDObj.getMixResStr(GDObj.Type.NUM, GDObj.Num.HERO_EXP, baseRow.refineExp)).multiply(wantRefineNum).consume(role);
        if (!consumeRes.ok()) {
            role.getGame().notice.tipResItem(role, consumeRes.data);
            return r.fail(consumeRes);
        }
        long now = System.currentTimeMillis();
        refineLevel = level;
        refineBeginTime = now;
        refineExpireTime = wantRefineNum * additionBaseRow.refineSeconds * 1000L + now;
        refineNum = wantRefineNum;
        noticeUpdate();
        return r;
    }

    @JsonIgnore
    private HeroShareBaseRow getBase() {
        return  role.getGame().table.worldTree.heroShareBase.get(1);
    }

    @JsonIgnore
    public GameResult<Void> getRefineReward() {
        GameResult<Void> r = new GameResult<>();
        HeroShareBaseRow baseRow = getBase();
        if (baseRow == null || baseRow.openStarNeed > getMaxStar()) {
            return r.fail("加成功能未开启");
        }
        if (refineNum < 1) {
            return r.fail("请先炼制");
        }
        WorldTreeAdditionBaseRow additionBaseRow = role.getGame().table.worldTree.additionBase.get(level);
        if (additionBaseRow == null) {
            return r.fail("无法领取奖励");
        }
        int realRefinedNum = 0;
        if (refineExpireTime > System.currentTimeMillis()) {
            long remainTime = refineExpireTime - System.currentTimeMillis();
            int remainNum = (int) (remainTime / (additionBaseRow.refineSeconds * 1000L));
            boolean halfRefine = remainTime % (additionBaseRow.refineSeconds * 1000L) > 0;
            realRefinedNum = refineNum - remainNum - (halfRefine ? 1 : 0);
        } else {
            realRefinedNum = refineNum;
        }

        MixRes reward = new MixRes();
        if (realRefinedNum > 0) {
            reward.addList(new MixRes(baseRow.rewardStr).multiply(realRefinedNum));
        }
        if (realRefinedNum < refineNum) {
            reward.addList(new MixRes(GDObj.getMixResStr(GDObj.Type.NUM, GDObj.Num.HERO_EXP, baseRow.refineExp)).multiply(refineNum - realRefinedNum));
        }
        new MixResAdder()
                .setRes(reward)
                .setSendMailWhenFull(true)
                .setOperation(GDOperation.WORLD_TREE_REFINE_REWARD)
                .setOperationSub(level)
                .setDialogReward(true)
                .exe(role);
        reset();
        noticeUpdate();
        return r;
    }

    private void reset() {
        refineNum = 0;
        refineLevel = 0;
        refineBeginTime = 0;
        refineExpireTime = 0;
    }

    @JsonIgnore
    private int getMaxStar() {
        return role.getRes().worldTree.heroShare.shareStarMax;
    }

    public void noticeUpdate() {
        role.sendNow(new WorldTreeAdditionDataResp(this));
    }

    @JsonIgnore
    public FightAttr getAttr() {
        FightAttr attr = new FightAttr();
        WorldTreeAdditionBaseRow additionBaseRow = role.getGame().table.worldTree.additionBase.get(level);
        if (additionBaseRow != null) {
            attr.parse(additionBaseRow.attrStr);
            WorldTreeAdditionScaleRow scaleRow = role.getGame().table.worldTree.additionScale.get(getMaxStar());
            if (scaleRow != null) {
                attr.scale(1 + scaleRow.scale / 10000d);
            }
        }
        return attr;
    }
}
